#ifndef rtti_h__
#define rtti_h__

// Macro for declaring RTTI support on a class
#define RTTI_DECL(CLASS)\
	private:\
		static gecko::Rtti s_rtti;\
	public:\
		static const gecko::Rtti& TYPE()\
		{\
			return s_rtti;\
		}\
		virtual const gecko::Rtti& Type()\
		{\
		return s_rtti;\
		}\

// Macro for implementing RTTI support on a class with no base class
#define RTTI_IMPL_NO_BASE(CLASS) \
	gecko::Rtti CLASS::s_rtti;

// Macro for implementing RTTI support on a class with a base class
#define RTTI_IMPL(CLASS, PARENTCLASS) \
	gecko::Rtti CLASS::s_rtti(&PARENTCLASS::TYPE());

namespace gecko
{

	// Fast pointer-compare runtime type information.
	//
	// To add runtime type information to a class, define a class like this:
	//
	//	class BaseClass
	//	{
	//		RTTI_DECL(BaseClass)
	//	};
	//
	//	Then in the cpp file, add this to the top of the file:
	//
	//	RTTI_IMPL_NO_BASE(BaseClass)
	//
	// Similarly, for a class derived from a base, do this:
	//
	//	class MyClass : public BaseClass
	//	{
	//		RTTI_DECL(MyClass)
	//	};
	//
	// Then in the cpp:
	//
	//	RTTI_IMPL(MyClass, BaseClass)
	//
	// NOTE: Be sure to put the DECL macro at the top of the class before any public/private/protected sections.
	//
	// To check against RTTI of two classes:
	//
	//	if ( t1.Type().IsOfType(t2.Type()) )
	//
	// or:
	//
	//	if ( t1.Type().IsOfType(MyClass::Type()) )
	//
	// or:
	//
	//	if ( t1.Type().IsDerivedFrom(BaseClass::Type()) )
	//
	class Rtti
	{
	public:
		// Default constructor.
		Rtti(const Rtti* parentRtti = 0);

		// Tests two types for equality.
		bool IsOfType(const Rtti& rtti) const;

		// Tests two types to see if one derives from the other.
		bool IsDerivedFrom(const Rtti& rtti) const;

	private:
		// disallow copy constructor
		Rtti(const Rtti& rhs);

	private:
		const Rtti* m_parentRtti;
	};

	inline Rtti::Rtti(const Rtti* parentRtti)
	: m_parentRtti(parentRtti)
	{
	}

	inline bool Rtti::IsOfType(const Rtti& rtti) const 
	{
		return (this == &rtti);
	}

}

#endif